/**
 * 
 */
package com.jm.web.tags.table;

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;

import com.jm.utils.StringHelper;
import com.jm.web.builder.table.TbodyBuilder;
import com.jm.web.data.BaseDataEntities;
import com.jm.web.data.BaseDataEntity;
import com.jm.web.data.ReturnData;
import com.jm.web.form.support.FormItem;
import com.jm.web.form.table.Tbody;
import com.jm.web.form.table.Td;
import com.jm.web.form.table.Tr;
import com.jm.web.tags.support.BaseTag;

/**
 * @author yanjie
 *
 * 2011/9/22 下午1:49:31
 */
public class TbodyTag extends BaseTag{
	private static final long serialVersionUID = 1240443437589642800L;
	
	protected TableTag tableTag = null;
	protected Object oDataSet = null;
	protected Object row_1 = null;
	private int curow_index = 0 ;
	protected ResultSet rs_1 = null;
	protected Iterator it = null;
	
	protected List trList = null;//记录tr,合并单元格的时候使用
	protected Map lastTdMap = null;//记录上一个td集合,合并单元格的时候使用
	protected String groupValue = "";
	protected String lastGroupValue = "";
	protected Map groupValueMap = null;//2层及2层以上合并用到
	protected Map lastGroupValueMap = null;//2层及2层以上合并用到
	protected BaseDataEntity subGroups = null;//2层及2层以上合并用到
	protected BaseDataEntity tdIndex = null;//2层及2层以上合并用到 記錄td的index
	protected Map totalTrMap = null ;//記錄小計行

	@Override
	public String getBuilderName() {
		return TbodyBuilder.class.getName();
	}
	
	@Override
	protected void preStartTag() {
		if(this.getParent() != null && this.getParent() instanceof TableTag){
			this.tableTag = (TableTag)this.getParent();
			if(this.IsContainsKey("dataSet")){
				this.oDataSet = this.GetExtValue("dataSet");
			}else{
				this.oDataSet = this.tableTag.GetExtValue("dataSet");
			}
			
			this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW_LASTRECORD,false);
		}
		
		if(this.isAutoMerge()){
			this.trList = new ArrayList();
			this.lastTdMap = new HashMap();
			this.tdIndex = new BaseDataEntity();
			if(this.isAutoMerge2()){
				this.groupValueMap = new HashMap();
				this.lastGroupValueMap = new HashMap();
			}
		}
		
		if(this.isSubtotal()){
			this.totalTrMap = new HashMap();
		}
		
		super.preStartTag();
	}
	
	@Override
	protected void preEndTag() {
		super.preEndTag();
	}
	
	@Override
	public void clear() {
		this.tableTag = null ;
		this.oDataSet = null;
		this.row_1 = null;
		this.rs_1 = null;
		this.curow_index = 0;
		this.it = null;
		this.trList = null;
		this.lastTdMap = null;
		this.groupValue = "";
		this.lastGroupValue = "";
		this.groupValueMap = null;
		this.lastGroupValueMap = null;
		this.subGroups = null;
		super.clear();
	}
	
	public TableTag getTableTag() {
		return tableTag;
	}
	
	public String getBodyDivID() {
		return StringHelper.Format("%1$s-body-div",this.tableTag.getId());
	}
	
	@Override
	protected int onStartTag() {
		if(!this.getPage().isFastExport() || this.oDataSet == null)
			return super.onStartTag();
		else if(this.oDataSet == null || this.oDataSet instanceof String){
			if(this.tableTag.GetExtValue("loopfisrt",false)){//沒有資料也要循環一次
				this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW,null);
				this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW_INDEX,this.curow_index);
				this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW_LASTRECORD,true);
				return super.onStartTag();
			}else{
				return SKIP_BODY;
			}
		}
		
		try {
			if(this.oDataSet instanceof Map && this.it == null)this.it=((Map)this.oDataSet).keySet().iterator();
			
			if(this.oDataSet instanceof ResultSet && ((ResultSet)this.oDataSet).next()){
				rs_1 = (ResultSet)this.oDataSet;
				this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW,rs_1);
				this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW_INDEX,this.curow_index);
				
				//判断是不是最后一笔资料
				if(((ResultSet)rs_1).isLast())
					this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW_LASTRECORD,true);
				
				if(this.getPage().isExportFile() && this.isEp()){
//					this.getPage().getExportAction().closeFile();
//					this.getPage().getExportAction().openCon();//打开xls odbc 连接
					return EVAL_BODY_BUFFERED;
				}else
					return super.onStartTag();
			}else if(this.oDataSet instanceof BaseDataEntities && this.curow_index == 0){
				BaseDataEntities rows = (BaseDataEntities)this.oDataSet;
				if(rows.size() >0){
					row_1 = rows.get(this.curow_index);
					this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW,row_1);
					this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW_INDEX,this.curow_index);
					
					//判断是不是最后一笔资料
					if(this.curow_index+1 == rows.size())
						this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW_LASTRECORD,true);
					
					if(this.getPage().isExportFile() && this.isEp()){
//						this.getPage().getExportAction().closeFile();
//						this.getPage().getExportAction().openCon();//打开xls odbc 连接
						return EVAL_BODY_BUFFERED;
					}else
						return super.onStartTag();
				}
			}else if(this.oDataSet instanceof List && this.curow_index == 0){
				List rows = (List)this.oDataSet;
				if(rows.size() >0){
					//判断是不是最后一笔资料
					if(this.curow_index+1 == ((List)this.oDataSet).size())
						this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW_LASTRECORD,true);
					
					Object object = rows.get(this.curow_index);
					if(object instanceof BaseDataEntity){
						row_1 = (BaseDataEntity)rows.get(this.curow_index);
						this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW,row_1);
						this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW_INDEX,this.curow_index);
						
						if(this.getPage().isExportFile() && this.isEp()){
							return EVAL_BODY_BUFFERED;
						}else
							return super.onStartTag();
					}else{
						row_1 = rows.get(this.curow_index);
						this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW,row_1);
						this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW_INDEX,this.curow_index);
						
						if(this.getPage().isExportFile() && this.isEp()){
							return EVAL_BODY_BUFFERED;
						}else
							return super.onStartTag();
					}
				}
			}else if(this.oDataSet instanceof Map && this.it.hasNext()){
				row_1 = ((Map)this.oDataSet).get(this.it.next());
				this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW,row_1);
				this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW_INDEX,this.curow_index);
				//判断是不是最后一笔资料
				if(this.curow_index+1 == ((Map)this.oDataSet).size())
					this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW_LASTRECORD,true);
				
				if(this.getPage().isExportFile() && this.isEp()){
					return EVAL_BODY_BUFFERED;
				}else
					return super.onStartTag();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		if(this.tableTag.GetExtValue("loopfisrt",false)){//沒有資料也要循環一次
			this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW,null);
			this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW_INDEX,this.curow_index);
			this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW_LASTRECORD,true);
			return super.onStartTag();
		}else{
			return SKIP_BODY;
		}
	}
	
	@Override
	public int doAfterBody() throws JspException {
		if(this.getBodyContent() != null){
			try {
				Tbody tbody = new Tbody();
				tbody.InitTag(this);
				FormItem.LoadFromXML(StringHelper.Format("<tbody>%1$s</tbody>",this.bodyContent.getString().trim()),tbody);
				tbody.init();
				this.getPage().getExportAction().exportTbody(this,tbody);
				this.getBodyContent().clear();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		if(!this.getPage().isFastExport() ||this.oDataSet == null)
			return super.doAfterBody();
		else if(this.oDataSet == null || this.oDataSet instanceof String){
			return SKIP_BODY;
		}
			
		try {
			if(this.oDataSet instanceof ResultSet && ((ResultSet)this.oDataSet).next()){
				rs_1 = (ResultSet)this.oDataSet;
				this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW,rs_1);
				this.curow_index++;
				this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW_INDEX,this.curow_index);
//				判断是不是最后一笔资料
				if(((ResultSet)rs_1).isLast())
					this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW_LASTRECORD,true);
				
				return EVAL_BODY_AGAIN;
			}else if(this.oDataSet instanceof BaseDataEntities){
				BaseDataEntities rows = (BaseDataEntities)this.oDataSet;
				this.curow_index++;
				if(this.curow_index <rows.size()){
					row_1 = rows.get(this.curow_index);
					this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW,row_1);
					this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW_INDEX,this.curow_index);
					
//					判断是不是最后一笔资料
					if(this.curow_index+1 == rows.size())
						this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW_LASTRECORD,true);
					return EVAL_BODY_AGAIN;
				}
			}else if(this.oDataSet instanceof List){
				List rows = (List)this.oDataSet;
				this.curow_index++;
				if(this.curow_index <rows.size()){
//					判断是不是最后一笔资料
					if(this.curow_index+1 == ((List)this.oDataSet).size())
						this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW_LASTRECORD,true);
					
					Object object = rows.get(this.curow_index);
					if(object instanceof BaseDataEntity){
						row_1 = (BaseDataEntity)rows.get(this.curow_index);
						this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW,row_1);
						this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW_INDEX,this.curow_index);
						return EVAL_BODY_AGAIN;
					}else{
						row_1 = rows.get(this.curow_index);
						this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW,row_1);
						this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW_INDEX,this.curow_index);
						return EVAL_BODY_AGAIN;
					}
				}
			}else if(this.oDataSet instanceof Map && this.it.hasNext()){
				row_1 = ((Map)this.oDataSet).get(this.it.next());
				this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW,row_1);
				this.curow_index++;
				this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW_INDEX,this.curow_index);
//				判断是不是最后一笔资料
				if(this.curow_index+1 == ((Map)this.oDataSet).size())
					this.getPage().getReturnData().setTableData(ReturnData.KEY_TABLE_ROW_LASTRECORD,true);
				return EVAL_BODY_AGAIN;
			}
				
			rs_1 = null;
			row_1 = null;
			return SKIP_BODY;
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return SKIP_BODY;
		
	}
	
	@Override
	protected int onEndTag() {
		this.getPage().getExportAction().closeCon(); //关闭xls odbc 连接
		return super.onEndTag();
	}
	
	
	
	/**
	 * @param strValue
	 */
	public void setGroup(String strValue) {
		SetExtValue("group",strValue);
	}
	
	/**
	 * @param strValue
	 * subGroup="group1:'danhao,chkTimes'"
	 */
	public void setSubGroup(String strValue) {
		SetExtValue("subGroup",strValue);
	}
	
	public void setStyle(String strValue) {
		SetExtValue("style",strValue);
	}
	
	public void setStyleClass(String strValue) {
		SetExtValue("class",strValue);
	}
	
	public void setExtAtr(String strValue) {
		SetExtValue("extAtr",strValue);
	}
	public void setDataSet(Object obj) {
		this.SetExtValue("dataSet", obj == null ? "" : obj);
		this.getPage().setFastExport(true);
	}
	
	/**
	 * @return
	 * 是否要自動合并單元格
	 */
	public boolean isAutoMerge(){
		return !StringHelper.IsNullOrEmpty(this.GetExtValue("group",""));
	}
	
	public boolean isAutoMerge2(){
		return !StringHelper.IsNullOrEmpty(this.GetExtValue("subGroup",""));
	}
	
	public void outHtml(JspWriter out){
		if(this.trList != null){
			String stripClass = ""; 
			if(this.tableTag.GetExtValue("stripe1",false) && trList.size() > 0){
				int mergeindex = ((Td)((Tr)trList.get(0)).getTds().get(0)).GetExtValue("mergeindex",0);
				stripClass = (mergeindex%2 == 0 ? "tr-darkstrip" : "tr-lightstrip");
			}
			
			for (int i = 0; i < this.trList.size(); i++) {
				((Tr)trList.get(i)).outHtml(out,stripClass);
			}
		}
	}

	public Map getLastTdMap() {
		return lastTdMap;
	}

	public void setLastTdMap(Map lastTdMap) {
		this.lastTdMap = lastTdMap;
	}
	
	public Td getLastTd(String key){
		if(this.lastTdMap == null) return null;
		return (Td)this.lastTdMap.get(key);
	}
	
	public Tr getLastTr(){
		if(trList == null || trList.size() == 0) return null;
		return (Tr)this.trList.get(this.trList.size() -1);
	}
	
	public List getTrList() {
		return trList;
	}

	public void setTrList(List trList) {
		this.trList = trList;
	}
	
	public String getGroup(){
		return this.GetExtValue("group","");
	}
	
	public String getGroupValue() {
		return groupValue;
	}
	
	public String getGroupValue(String key) {
		if(this.groupValueMap == null || this.groupValueMap.size() ==0) return "";
		return StringHelper.getValue(this.groupValueMap.get(key));
	}
	
	public void setGroupValue(String groupValue) {
		this.groupValue = groupValue;
	}

	public String getLastGroupValue() {
		return lastGroupValue;
	}
	
	public String getLastGroupValue(String key) {
		if(this.lastGroupValueMap == null || this.lastGroupValueMap.size() ==0) return "";
		return StringHelper.getValue(this.lastGroupValueMap.get(key));
	}

	public void setLastGroupValue(String lastGroupValue) {
		this.lastGroupValue = lastGroupValue;
	}
	
	public BaseDataEntity getSubGroups(){
		if(subGroups != null) return subGroups;
		subGroups = BaseDataEntity.getConfig(this.GetExtValue("subGroup",""));
		return subGroups;
	}

	public Map getGroupValueMap() {
		return groupValueMap;
	}

	public void setGroupValueMap(Map groupValueMap) {
		this.groupValueMap = groupValueMap;
	}

	public Map getLastGroupValueMap() {
		return lastGroupValueMap;
	}

	public void setLastGroupValueMap(Map lastGroupValueMap) {
		this.lastGroupValueMap = lastGroupValueMap;
	}

	public BaseDataEntity getTdIndex() {
		return tdIndex;
	}
	
	//以下處理小計合計
	public boolean isSubtotal(){
		return !StringHelper.IsNullOrEmpty(this.GetExtValue("subTotal",""));
	}
	
	/**
	 * @param strValue
	 * 小計,可以有好幾個
	 */
	public void setSubTotal(String strValue) {
		SetExtValue("subTotal",strValue);
	}
	
	/**
	 * @param strValue
	 * 總計只會有一個
	 */
	public void setGrandSubtotal(String strValue) {
		SetExtValue("grandTotal",strValue);
	}
	
	/**
	 * @param lev
	 * 加入小計后,重新計算單元格的合并
	 */
	public void reCalculateRowspan(int lev){
		if(this.trList == null && this.trList.size() == 0) return ;
		for (int i = 0; i < this.trList.size(); i++) {
			Tr tr = (Tr)this.trList.get(i);
			if(tr.getTds() == null) continue;
			for (int j = 0; j < tr.getTds().size(); j++) {
				Td td = (Td)tr.getTds().get(j);
				if(td.getGroupLev() >= 0 && td.getGroupLev() < lev){
					td.setRowspan(td.getRowspan()+1);
//					System.out.println(td.getRowspan()+"----------"+td.getTdEndHtml());		
				}
			}
		}
	}
}
